package com.ruoyi.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.EventAndTopic;
import com.ruoyi.system.domain.PoPublicOpinion;
import com.ruoyi.system.domain.PublicOpinionEvents;
import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.enums.ChinaMediaTypeEnum;
import com.ruoyi.system.mapper.PoPublicOpinionMapper;
import com.ruoyi.system.mapper.PublicOpinionEventsMapper;
import com.ruoyi.system.service.*;
import com.ruoyi.system.task.WarningTask;
import com.ruoyi.system.util.SSLClient;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.TopHitsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

import static cn.hutool.crypto.SecureUtil.md5;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * 舆情Service业务层处理
 *
 * @author ruoyi
 */
@Service
public class PoPublicOpinionServiceImpl implements IPoPublicOpinionService {
    @Autowired
    private PoPublicOpinionMapper poPublicOpinionMapper;

    @Autowired
    private PublicOpinionEventsMapper publicOpinionEventsMapper;

    @Autowired
    WarningTask warningTask;

    @Autowired
    private EsUtil esUtil;

    @Autowired
    private ElasticsearchBasicService elasticsearchBasicService;

    @Autowired
    private NlpcUtil nlpcUtil;

    @Autowired
    private IPublicOpinionEventsService publicOpinionEventsService;

    @Autowired
    private IPublicOpinionTopicService publicOpinionTopicService;

    @Autowired
    private ISearchHotKeyService searchHotKeyService;

    @Autowired
    ElasticsearchQueryBuilderService elasticsearchQueryBuilderService;

    private static Logger logger = LogManager.getRootLogger();

    private final ObjectMapper objectMapper = new ObjectMapper();



    @Value("${sina.baseUrl}")
    String baseUrl;

    @Value("${sina.apiUrl}")
    String apiUrl;

    @Value("${sina.appId}")
    String appId;

    @Value("${sina.appSecret}")
    String appSecret;

    @Value("${sina.authorizeCodeUrl}")
    String authorizeCodeUrl;

    @Value("${sina.accessTokenUrl}")
    String accessTokenUrl;

    //认证码
    private static String authorizeCode;
    //授权校验参数
    private static String accessToken;

    /**
     * 获取授权码
     * @return
     */
    public String getAccessToken() {
        //1、申请认证码
        String authorizeCodeRequestUrl = baseUrl + authorizeCodeUrl;
        Map<String, String> authorizeCodeParams = new HashMap<>();
        authorizeCodeParams.put("appId", appId);
        authorizeCodeParams.put("responseType", "code");
        authorizeCodeParams.put("state", "state");
        //post方式
        String authorizeCodeJson = sendPost(authorizeCodeRequestUrl, authorizeCodeParams);
        authorizeCode = JSON.parseObject(authorizeCodeJson).getJSONObject("authorizeCode").getString("authorizeCode");
        System.out.println("authorizeCode:" + authorizeCode);

        //2、获取授权码
        authorizeCodeParams = new HashMap<>();
        authorizeCodeParams.put("appId", appId);
        authorizeCodeParams.put("appSecret", appSecret);
        authorizeCodeParams.put("grantType", "authorization_code");
        authorizeCodeParams.put("authorizeCode", authorizeCode);
        String accessTokenRequestUrl = baseUrl + accessTokenUrl;
//        String accessTokenJson = sendGet(accessTokenRequestUrl, authorizeCodeParams);
        //post方式
        String accessTokenJson = sendPost(accessTokenRequestUrl, authorizeCodeParams);
        System.out.println(accessTokenJson);
        accessToken = JSON.parseObject(accessTokenJson).getJSONObject("accessToken").getString("accessToken");
        System.out.println("accessToken:" + accessToken);
        return accessToken;
    }




    /**
     * 发送POST请求
     *
     * @param url
     * @param params
     * @return
     */
    public static String sendPost(String url, Map<String, String> params) {
        HttpClient httpClient = null;
        HttpPost httpPost = null;
        String urlWithParams = url;
        String rtnStr = null;
        try {
            httpClient = new SSLClient();
            httpPost = new HttpPost(urlWithParams);

            if (params != null && !params.isEmpty()) {
                List<NameValuePair> postParams = new ArrayList<NameValuePair>();
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    postParams.add(new BasicNameValuePair(entry.getKey(), entry
                            .getValue()));
                }

                urlWithParams += "?"
                        + org.apache.commons.lang3.StringUtils.join(postParams.toArray(), "&");

                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(
                        postParams, "UTF-8");
                httpPost.setEntity(entity);
            }
            System.out.println("POST URL = [" + urlWithParams + "]");
            HttpResponse httpResponse = httpClient.execute(httpPost);
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                org.apache.http.HttpEntity resEntity = httpResponse.getEntity();
                rtnStr = EntityUtils.toString(resEntity, "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (httpPost != null)
                httpPost.releaseConnection();
        }
        return rtnStr;
    }








    /**
     * 批量新增舆情
     *
     * @param opinions 舆情
     * @return 结果
     */
    @Override
    public int insertPoPublicOpinionBatch(List<PoPublicOpinion> opinions) {
        esUtil.indexBatchOpinion(opinions);
        return 1;
    }


    /**
     * 查询舆情
     *
     * @param id 舆情ID
     * @return 舆情
     */
    @Override
    public PoPublicOpinion selectPoPublicOpinionById(String id) {
        return esUtil.selectPoPublicOpinionById(id);
    }


    /**
     * 查询舆情列表
     *
     * @param poPublicOpinion 舆情
     * @return 舆情
     */
    @Override
    public List<PoPublicOpinion> selectPoPublicOpinionList(PoPublicOpinion poPublicOpinion) {
        return poPublicOpinionMapper.selectPoPublicOpinionList(poPublicOpinion);
    }


    /**
     * 新增舆情
     *
     * @param poPublicOpinion 舆情
     * @return 结果
     */
    @Override
    public int insertPoPublicOpinion(PoPublicOpinion poPublicOpinion) {
        return poPublicOpinionMapper.insertPoPublicOpinion(poPublicOpinion);
    }

    /**
     * 修改舆情
     *
     * @param poPublicOpinion 舆情
     * @return 结果
     */
    @Override
    public int updatePoPublicOpinion(PoPublicOpinion poPublicOpinion) {
        return poPublicOpinionMapper.updatePoPublicOpinion(poPublicOpinion);
    }

    /**
     * 批量删除舆情
     *
     * @param ids 需要删除的舆情ID
     * @return 结果
     */
    @Override
    public int deletePoPublicOpinionByIds(Long[] ids) {
        return poPublicOpinionMapper.deletePoPublicOpinionByIds(ids);
    }

    /**
     * 删除舆情信息
     *
     * @param id 舆情ID
     * @return 结果
     */
    @Override
    public int deletePoPublicOpinionById(Long id) {
        return poPublicOpinionMapper.deletePoPublicOpinionById(id);
    }


    @Override
    public List<CountResultVo> queryMediaTypeByEventId(Long eventId, EventParameterVo parameterVo) {
        PublicOpinionEvents opinionEvent = publicOpinionEventsMapper.selectPublicOpinionEventsById(eventId);
        EventQueryParameterVo vo = new EventQueryParameterVo();
        //事件的条件
        vo.setExclusionWords(opinionEvent.getExclusionWords());
        vo.setOpinionWords(opinionEvent.getOpinionWords());
        vo.setRelatedWords(opinionEvent.getRelatedWords());
        vo.setStartTime(opinionEvent.getStartTime());
        vo.setEndTime(opinionEvent.getEndTime());
        vo.setSearchArea(opinionEvent.getSearchArea());
        //前端的条件
        vo.setStartDateTime(parameterVo.getStartDateTime());
        vo.setEndDateTime(parameterVo.getEndDateTime());
        vo.setReadState(parameterVo.getReadState());
//        vo.setSensitiveInformation(parameterVo.getSensitiveInformation());
        vo.setTimeType(parameterVo.getTimeType());
        vo.setQueryArea(parameterVo.getSearchArea());
        vo.setKeyWords(parameterVo.getKeyWords());
        vo.setMediaType(parameterVo.getMediaType());

        List<CountResultVo> list = queryMediaTypeByEventId(vo);
        return list;
    }

    @Override
    public List<CountResultVo> queryMediaTypeByEventId(EventQueryParameterVo vo) {
        List<CountResultVo> list = poPublicOpinionMapper.queryMediaTypeByEventId(vo);
        return list;
    }


    @Override
    public EventParameterVo buildParameter(String timeType, String beginPublishDay, String endPublishDay) {
        EventParameterVo parameter = new EventParameterVo();
        parameter.setTimeType(timeType);
        if (StringUtils.isNotEmpty(beginPublishDay)) {
            parameter.setStartDateTime(DateUtils.parseDate(beginPublishDay));
        }
        if (StringUtils.isNotEmpty(endPublishDay)) {
            parameter.setEndDateTime(DateUtils.parseDate(endPublishDay));
        }
        return parameter;
    }



    @Override
    public List<PoPublicOpinion> selectPoPublicOpinionListNewest(int count) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.should(QueryBuilders.matchAllQuery());
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(boolQueryBuilder);
        //排序
        List<SortBuilder<?>> sorts = new ArrayList<>();
        SortBuilder sortBuilder = SortBuilders.fieldSort("publishTime").order(SortOrder.DESC);
        sorts.add(sortBuilder);
        searchSourceBuilder.sort(sorts);
        try {
            return esUtil.search(searchSourceBuilder, PoPublicOpinion.class, count);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }


    @Override
    public long getWarningCount(String beginPublishDay, String endPublishDay) {
        //总数
        List<String> opinionIds = poPublicOpinionMapper.queryWarningIds(null, null);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if (opinionIds != null && opinionIds.size() > 0) {
            boolQueryBuilder.must(QueryBuilders.termsQuery("id", opinionIds));
        }
        if (StringUtils.isNotEmpty(beginPublishDay)) {
            boolQueryBuilder= elasticsearchQueryBuilderService.boolQueryBuilderStartTime(boolQueryBuilder,DateUtils.parseDate(beginPublishDay));
        }
        if (StringUtils.isNotEmpty(endPublishDay)) {
            boolQueryBuilder= elasticsearchQueryBuilderService.boolQueryBuilderEndTime(boolQueryBuilder,DateUtils.parseDate(endPublishDay));
        }
        boolQueryBuilder.should(QueryBuilders.matchAllQuery());
        sourceBuilder.query(boolQueryBuilder);
        return esUtil.getAllOpinionCount(sourceBuilder);

    }

    @Override
    public List<String> getAllMediaType() {
        return poPublicOpinionMapper.queryAllMediaType();
    }


    /**
     * 获取事件的情感统计
     *
     * @param eventId
     * @return
     */
    @Override
    public OpTypeNumVM getTypeNumEvent(Long eventId, EventParameterVo parameter, List<String> bindIds) {
        //获取事件对象
        PublicOpinionEvents event = publicOpinionEventsService.selectPublicOpinionEventsById(eventId);
        OpTypeNumVM opTypeNumVM = new OpTypeNumVM();
        opTypeNumVM.setAllNum(getAllOpinionCount(null, parameter, null));
        opTypeNumVM.setRelatedInformation(getAllOpinionCount(event, parameter, bindIds));
        opTypeNumVM.setPositive(getPositiveOpinionCount(event, parameter, bindIds));
        opTypeNumVM.setNeutral(getNeutralOpinionCount(event, parameter, bindIds));
        opTypeNumVM.setNegative(getNegativeOpinionCount(event, parameter, bindIds));
        return opTypeNumVM;
    }



    ;

    @Override
    public long getAllOpinionCount(PublicOpinionEvents event, EventParameterVo parameter, List<String> bindIds) {
        //构建查询语句
        SearchSourceBuilder sourceBuilder = esUtil.buildSearchSourceBuilder(event, parameter, bindIds);
        return esUtil.getAllOpinionCount(sourceBuilder);

    }

    @Override
    public long getPositiveOpinionCount(PublicOpinionEvents event, EventParameterVo parameter, List<String> bindIds) {
        //用SearchSourceBuilder来构造查询请求体 ,请仔细查看它的方法，构造各种查询的方法都在这。
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder matchQueryBuilder = esUtil.buildBoolQueryBuilder(event, parameter, bindIds);
        matchQueryBuilder.must(QueryBuilders.termQuery("ispositive", 1));
        sourceBuilder.query(matchQueryBuilder);
        return esUtil.getAllOpinionCount(sourceBuilder);

    }

    @Override
    public long getNeutralOpinionCount(PublicOpinionEvents event, EventParameterVo parameter, List<String> bindIds) {
        //用SearchSourceBuilder来构造查询请求体 ,请仔细查看它的方法，构造各种查询的方法都在这。
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder matchQueryBuilder = esUtil.buildBoolQueryBuilder(event, parameter, bindIds);
        matchQueryBuilder.must(QueryBuilders.termQuery("isneutral", 1));
        sourceBuilder.query(matchQueryBuilder);
        return esUtil.getAllOpinionCount(sourceBuilder);

    }

    @Override
    public long getNegativeOpinionCount(PublicOpinionEvents event, EventParameterVo parameter, List<String> bindIds) {
        //用SearchSourceBuilder来构造查询请求体 ,请仔细查看它的方法，构造各种查询的方法都在这。
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder matchQueryBuilder = esUtil.buildBoolQueryBuilder(event, parameter, bindIds);
        matchQueryBuilder.must(QueryBuilders.termQuery("isnegative", 1));
        sourceBuilder.query(matchQueryBuilder);
        return esUtil.getAllOpinionCount(sourceBuilder);

    }





    @Override
    public List<NameValue> getMediaNameNum(Long eventId, EventParameterVo parameter, List<String> bindIds) {
        //查询事件
        PublicOpinionEvents event = publicOpinionEventsService.selectPublicOpinionEventsById(eventId);
        //构建查询语句
        SearchSourceBuilder sourceBuilder = esUtil.buildSearchSourceBuilder(event, parameter, bindIds);

        return esUtil.getCountGroupByMediaName(sourceBuilder);


    }

    @Override
    public List<NameListValue> groupSensitiveOpinionDayHour(String sensitiveInformation, EventParameterVo parameter) {
        if (parameter == null) {
            parameter = new EventParameterVo();
        }
        parameter.setIsnegative(1);

        //构造QueryBuilder
        BoolQueryBuilder matchQueryBuilder = QueryBuilders.boolQuery();

        if (StringUtils.isEmpty(parameter.getTimeType()) && parameter.getStartDateTime() != null) {
            matchQueryBuilder=elasticsearchQueryBuilderService.boolQueryBuilderStartTime(matchQueryBuilder,parameter.getStartDateTime());
        } else if (StringUtils.isEmpty(parameter.getTimeType()) && parameter.getEndDateTime() != null) {
            matchQueryBuilder=elasticsearchQueryBuilderService.boolQueryBuilderEndTime(matchQueryBuilder,parameter.getEndDateTime());
        }

        //情感过滤
        if (parameter.getIspositive() == 1) {
            matchQueryBuilder.must(QueryBuilders.termQuery("ispositive", parameter.getIspositive()));
        }
        if (parameter.getIsneutral() == 1) {
            matchQueryBuilder.must(QueryBuilders.termQuery("isneutral", parameter.getIsneutral()));
        }
        if (parameter.getIsnegative() == 1) {
            matchQueryBuilder.must(QueryBuilders.termQuery("isnegative", parameter.getIsnegative()));
        }
        //用SearchSourceBuilder来构造查询请求体 ,请仔细查看它的方法，构造各种查询的方法都在这。
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(matchQueryBuilder);
        try {
            return esUtil.getCountGroupByPublishDateAndPublishTime(sourceBuilder);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;

    }


    @Override
    public List<NameValue> getMediaTypeNum(Long eventId, EventParameterVo parameter, List<String> bindIds) {
        //查询事件
        PublicOpinionEvents event = publicOpinionEventsService.selectPublicOpinionEventsById(eventId);
        //构建查询语句
        SearchSourceBuilder sourceBuilder = esUtil.buildSearchSourceBuilder(event, parameter, bindIds);
        try {
            return esUtil.getCountGroupByMediaType(sourceBuilder);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public List<OpMediaNameNumVM> getMediaOverseasNum(List<String> opinionIds) {
        return poPublicOpinionMapper.countMediaOverseasOpinion(opinionIds);
    }

    @Override
    public List<NameValue> getOpinionByLanguageTypeCounts(List<String> opinionIds) {
        return poPublicOpinionMapper.getOpinionByLanguageTypeCounts(opinionIds);
    }





    @Override
    public List<NameListValue> getCountsByPublishDayMediaName(Long eventId, String beginPublishDay, String endPublishDay) {
        //查询事件
        PublicOpinionEvents event = publicOpinionEventsService.selectPublicOpinionEventsById(eventId);
        //绑定的舆情
        List<String> bindIds = publicOpinionEventsService.getMatchOpinionByEventIdForDataBase(eventId);
        EventParameterVo parameterVo = null;
        if (StringUtils.isNotEmpty(beginPublishDay) && StringUtils.isNotEmpty(endPublishDay)) {
            parameterVo = new EventParameterVo();
            parameterVo.setStartDateTime(DateUtils.parseDate(beginPublishDay));
            parameterVo.setEndDateTime(DateUtils.parseDate(endPublishDay));
        }
        SearchSourceBuilder sourceBuilder = esUtil.buildSearchSourceBuilder(event, parameterVo, bindIds);
        try {
            return esUtil.getCountGroupByPublishDateAndMediaName(sourceBuilder);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public int addToFavorites(String[] ids, Long userId, Long deptId, String tenantCode) {
        //先移除
        poPublicOpinionMapper.removeFavorites(ids, userId, deptId, tenantCode);
        return poPublicOpinionMapper.addToFavorites(ids, new Date(), userId, deptId, tenantCode);
    }


    @Override
    public List<String> getFavoriteIds(String tenantCode) {
        return poPublicOpinionMapper.getFavorites(tenantCode);
    }

    ;

    @Override
    public PageInfo<PoPublicOpinion> getFavorites(Long userId, Long deptId, String tenantCode, Integer pageNum, Integer pageSize) {
        List<String> favoriteIds = getFavoriteIds(tenantCode);
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if (favoriteIds != null) {
            boolQueryBuilder.must(QueryBuilders.termsQuery("id", favoriteIds));
        }
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(boolQueryBuilder);
        //排序
        List<SortBuilder<?>> sorts = new ArrayList<>();
        SortBuilder sortBuilder = SortBuilders.fieldSort("publishTime").order(SortOrder.DESC).unmappedType("keyword");
        sorts.add(sortBuilder);
        try {
            return esUtil.search(searchSourceBuilder, pageNum, pageSize, PoPublicOpinion.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public int removeFavorites(String[] ids, Long userId, Long deptId, String tenantCode) {
        return poPublicOpinionMapper.removeFavorites(ids, userId, deptId, tenantCode);
    }

    @Override
    public List<PoPublicOpinion> hotPublicOpinion(String beginPublishDay, String endPublishDay, int count) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.should(QueryBuilders.matchAllQuery());
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(boolQueryBuilder);
        //排序
        List<SortBuilder<?>> sorts = new ArrayList<>();
        SortBuilder sortBuilder = SortBuilders.fieldSort("comment").order(SortOrder.DESC);
        sorts.add(sortBuilder);
        searchSourceBuilder.sort(sorts);
        try {
            return esUtil.search(searchSourceBuilder, PoPublicOpinion.class, count);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ArrayList<>();

    }

    @Override
    public List<PoPublicOpinion> selectPoPublicOpinionListEventId(Long eventId) {
        PublicOpinionEvents event = publicOpinionEventsService.selectPublicOpinionEventsById(eventId);
        return esUtil.getEventOpinions(event, false);
    }


    @Override
    public PageInfo<PoPublicOpinion> hotPublicOpinion(Long eventId, String beginPublishDay, String endPublishDay, Integer pageNum, Integer pageSize, Integer informationType) {
        //获取事件的开始结束时间
        PublicOpinionEvents event = publicOpinionEventsMapper.selectPublicOpinionEventsById(eventId);
        //绑定的舆情
        List<String> bindIds = publicOpinionEventsService.getMatchOpinionByEventIdForDataBase(eventId);
        //绑定的舆情
        List<String> excludeIds = publicOpinionEventsService.getExcludeIdsByEventIdForDataBase(eventId);
        //查询参数
        EventParameterVo parameter = new EventParameterVo();
        if (StringUtils.isNotEmpty(beginPublishDay)) {
            parameter.setStartDateTime(DateUtils.parseDate(beginPublishDay));
        }
        if (StringUtils.isNotEmpty(endPublishDay)) {
            parameter.setEndDateTime(DateUtils.parseDate(endPublishDay));
        }
        BoolQueryBuilder boolQueryBuilder = esUtil.buildBoolQueryBuilder(event, parameter, bindIds, excludeIds);
        if (informationType != null) {
            boolQueryBuilder.must(QueryBuilders.termQuery("informationType", informationType));
        }

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(boolQueryBuilder);
        //排序
        List<SortBuilder<?>> sorts = new ArrayList<>();
        SortBuilder sortBuilder = SortBuilders.fieldSort("commentVolume").order(SortOrder.DESC).unmappedType("keyword");
        sorts.add(sortBuilder);
        sortBuilder = SortBuilders.fieldSort("forwardingVolume").order(SortOrder.DESC).unmappedType("keyword");
        sorts.add(sortBuilder);
        sortBuilder = SortBuilders.fieldSort("likeVolume").order(SortOrder.DESC).unmappedType("keyword");
        sorts.add(sortBuilder);
        searchSourceBuilder.sort(sorts);

        try {
            return esUtil.search(searchSourceBuilder, pageNum, pageSize, PoPublicOpinion.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 获取指定个数的事件关联地名
     *
     * @param maxCount
     * @return
     */
    @Override
    public List<NameValue> getLocationCount(List<String> opinionIds, int maxCount) {
        //构建查询语句
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(termsQuery("opinionId", opinionIds));
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(boolQueryBuilder);

        return esUtil.getCountGroupByRelationLocationName(searchSourceBuilder, maxCount);

    }

    /**
     * 获取指定个数的事件关联人物
     *
     * @param maxCount
     * @return
     */
    @Override
    public List<NameValue> getPersonCount(List<String> opinionIds, int maxCount) {
        //构建查询语句
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(termsQuery("opinionId", opinionIds));
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(boolQueryBuilder);

        return esUtil.getCountGroupByRelationPersonName(searchSourceBuilder, maxCount);

    }




    @Override
    public Map<String, Object> comprehensiveStatisticsThisYear() {
        List<String> months = poPublicOpinionMapper.getMonths();
        List<String> mediaTypes = poPublicOpinionMapper.getPoMediaTypes();
        //情感
        List<MonthMediaTypeCount> listPositive = poPublicOpinionMapper.getDataByMonthMediaTypeCount("正面");
        List<MonthMediaTypeCount> listNeutral = poPublicOpinionMapper.getDataByMonthMediaTypeCount("中性");
        List<MonthMediaTypeCount> listNegative = poPublicOpinionMapper.getDataByMonthMediaTypeCount("负面");
        //预警等级
        List<MonthMediaTypeCount> listRed = poPublicOpinionMapper.getDataByMonthMediaTypeCountForecast("red");
        List<MonthMediaTypeCount> listOrange = poPublicOpinionMapper.getDataByMonthMediaTypeCountForecast("orange");
        List<MonthMediaTypeCount> listYellow = poPublicOpinionMapper.getDataByMonthMediaTypeCountForecast("yellow");

        Map<String, List<Integer>> datasPositive = new HashMap<>();
        months.forEach(s -> {
            List<Integer> data = new ArrayList<>();
            listPositive.forEach(monthMediaTypeCount -> {
                if (s.equals(monthMediaTypeCount.getMonths())) {
                    data.add(monthMediaTypeCount.getCount());
                }

            });
            datasPositive.put(s, data);
        });

        Map<String, List<Integer>> datasNeutral = new HashMap<>();
        months.forEach(s -> {
            List<Integer> data = new ArrayList<>();
            listNeutral.forEach(monthMediaTypeCount -> {
                if (s.equals(monthMediaTypeCount.getMonths())) {
                    data.add(monthMediaTypeCount.getCount());
                }

            });
            datasNeutral.put(s, data);
        });

        Map<String, List<Integer>> datasNegative = new HashMap<>();
        months.forEach(s -> {
            List<Integer> data = new ArrayList<>();
            listNegative.forEach(monthMediaTypeCount -> {
                if (s.equals(monthMediaTypeCount.getMonths())) {
                    data.add(monthMediaTypeCount.getCount());
                }

            });
            datasNegative.put(s, data);
        });

        Map<String, List<Integer>> datasRed = new HashMap<>();
        months.forEach(s -> {
            List<Integer> data = new ArrayList<>();
            listRed.forEach(monthMediaTypeCount -> {
                if (s.equals(monthMediaTypeCount.getMonths())) {
                    data.add(monthMediaTypeCount.getCount());
                }

            });
            datasRed.put(s, data);
        });

        Map<String, List<Integer>> datasOrange = new HashMap<>();
        months.forEach(s -> {
            List<Integer> data = new ArrayList<>();
            listOrange.forEach(monthMediaTypeCount -> {
                if (s.equals(monthMediaTypeCount.getMonths())) {
                    data.add(monthMediaTypeCount.getCount());
                }

            });
            datasOrange.put(s, data);
        });

        Map<String, List<Integer>> datasYellow = new HashMap<>();
        months.forEach(s -> {
            List<Integer> data = new ArrayList<>();
            listYellow.forEach(monthMediaTypeCount -> {
                if (s.equals(monthMediaTypeCount.getMonths())) {
                    data.add(monthMediaTypeCount.getCount());
                }

            });
            datasYellow.put(s, data);
        });

        Map<String, Object> map = new HashMap<>();
        map.put("months", months);
        map.put("mediaTypes", mediaTypes);
        map.put("datasPositive", datasPositive);
        map.put("datasNeutral", datasNeutral);
        map.put("datasNegative", datasNegative);
        map.put("datasRed", datasRed);
        map.put("datasOrange", datasOrange);
        map.put("datasYellow", datasYellow);
        return map;
    }


    /**
     * 事件正负面观点分析
     *
     * @param event
     * @param parameter
     * @param bindIds
     * @return
     */
    @Override
    public List<PoPublicOpinion> getViewpointAnalysis(PublicOpinionEvents event, EventParameterVo parameter, List<String> bindIds) {

        //构建查询语句
        BoolQueryBuilder boolQueryBuilder = esUtil.buildBoolQueryBuilder(event, parameter, bindIds);

        // 添加ispositive为1的条件
        boolQueryBuilder.should(QueryBuilders.termQuery("ispositive", 1));

        // 添加isnegative为1的条件
        boolQueryBuilder.should(QueryBuilders.termQuery("isnegative", 1));

        // 设置最小匹配数
        boolQueryBuilder.minimumShouldMatch(1);

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(boolQueryBuilder);
        try {
            return esUtil.search(searchSourceBuilder, 1, 100, PoPublicOpinion.class).getList();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }

    @Override
    public List<NameValue> getCountGroupByPublishDate(Long eventId, EventParameterVo parameter, List<String> bindIds) {
        //查询事件
        PublicOpinionEvents event = publicOpinionEventsService.selectPublicOpinionEventsById(eventId);
        //构建查询语句
        SearchSourceBuilder sourceBuilder = esUtil.buildSearchSourceBuilder(event, parameter, bindIds);

        return esUtil.getCountGroupByPublishDate(sourceBuilder);


    }


    @Override
    public List<String> getRelationPersonNames(String id) {
        PoPublicOpinion opinion = selectPoPublicOpinionById(id);
        String text=opinion.getTitle()+opinion.getContent();
        List<String> keywords = nlpcUtil.getPersons(text, 30);
        return keywords;
    }

    @Override
    public List<String> getRelationLocationNames(String id) {
        PoPublicOpinion opinion = selectPoPublicOpinionById(id);
        String text=opinion.getTitle()+opinion.getContent();
        List<String> keywords = nlpcUtil.getLocations(text, 30);
        return keywords;
    }


    @Override
    public List<String> getRelationOrganizationNames(String id) {
        PoPublicOpinion opinion = selectPoPublicOpinionById(id);
        String text=opinion.getTitle()+opinion.getContent();
        List<String> keywords = nlpcUtil.getOrganizations(text, 30);
        return keywords;
    }



    @Override
    public List<OpMediaNameSensitiveDayNumVM> countSensitiveOpinionByMediaName(Long eventId, EventParameterVo parameter, List<String> bindIds) {
        //获取事件的开始结束时间
        PublicOpinionEvents event = publicOpinionEventsMapper.selectPublicOpinionEventsById(eventId);
        //排除的舆情
        List<String> excludeIds = publicOpinionEventsService.getExcludeIdsByEventIdForDataBase(eventId);
        //构建查询语句
        BoolQueryBuilder boolQueryBuilder = esUtil.buildBoolQueryBuilder(event, parameter, bindIds, excludeIds);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(boolQueryBuilder);
        return esUtil.getCountSensitiveOpinionByMediaName(searchSourceBuilder);
    }


    @Override
    public List<OpAuthorSensitiveDayNumVM> countSensitiveAuthorOpinion(Long eventId, EventParameterVo parameter, List<String> bindIds) {
        //获取事件的开始结束时间
        PublicOpinionEvents event = publicOpinionEventsMapper.selectPublicOpinionEventsById(eventId);
        //排除的舆情
        List<String> excludeIds = publicOpinionEventsService.getExcludeIdsByEventIdForDataBase(eventId);
        //构建查询语句
        BoolQueryBuilder boolQueryBuilder = esUtil.buildBoolQueryBuilder(event, parameter, bindIds, excludeIds);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(boolQueryBuilder);
        return esUtil.getCountSensitiveOpinionByAuthor(searchSourceBuilder);
    }

    @Override
    public List<NameListValue> getMediaTypeSensitiveDayNumEvent(Long eventId, EventParameterVo parameter, List<String> bindIds) {
        //查询事件
        PublicOpinionEvents event = publicOpinionEventsService.selectPublicOpinionEventsById(eventId);
        //构建查询语句
        SearchSourceBuilder sourceBuilder = esUtil.buildSearchSourceBuilder(event, parameter, bindIds);
        try {
            return esUtil.getCountGroupByMediaTypeAndSensitiveInformation(sourceBuilder);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public List<KeywordInfo> getHotWords(String id) {
        PoPublicOpinion opinion = selectPoPublicOpinionById(id);
        String text=opinion.getTitle()+opinion.getContent();
        List<KeywordInfo> keywords = nlpcUtil.getHotWords(text, 30);
        List<OpinionKeyword> keys = new ArrayList<>();
        keywords.forEach(keywordInfo -> {
            OpinionKeyword word = new OpinionKeyword();
            word.setKeyword(keywordInfo.getKeyword());
            word.setOpinionId(id);
            keys.add(word);
        });
        if (keys.size() > 0) {
            esUtil.indexBatchKeyWords(keys);
        }
        return keywords;
    }


    @Override
    public PageInfo<PoPublicOpinion> getOpinionsOfSameAuthorById(String id, String author, Integer pageNum, Integer pageSize) {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //构建查询语句
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.mustNot(QueryBuilders.termQuery("id", id));
        boolQueryBuilder.must(QueryBuilders.termQuery("author", author));
        searchSourceBuilder.query(boolQueryBuilder);
        try {
            return esUtil.search(searchSourceBuilder, pageNum, pageSize, PoPublicOpinion.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public PageInfo<PoPublicOpinion> getOpinionsOfSimilarArticlesById(String id, String title, Integer pageNum, Integer pageSize) {

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //构建查询语句
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.mustNot(QueryBuilders.termQuery("id", id));
        boolQueryBuilder.must(QueryBuilders.matchQuery("title", title));
        searchSourceBuilder.query(boolQueryBuilder);
        try {
            return esUtil.search(searchSourceBuilder, pageNum, pageSize, PoPublicOpinion.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }

    /**
     * 获取事件的首发媒体
     *
     * @param eventId
     * @param parameter
     * @param bindIds
     * @return
     */
    @Override
    public List<PoPublicOpinion> getStartingMedia(Long eventId, EventParameterVo parameter, List<String> bindIds) {
        //查询事件
        PublicOpinionEvents event = publicOpinionEventsService.selectPublicOpinionEventsById(eventId);
        //排除的舆情
        List<String> excludeIds = publicOpinionEventsService.getExcludeIdsByEventIdForDataBase(eventId);
        //构建查询语句
        BoolQueryBuilder boolQueryBuilder = esUtil.buildBoolQueryBuilder(event, parameter, bindIds, excludeIds);

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(boolQueryBuilder);
        //获取事件相关全部媒体
        try {
            return esUtil.getCountGroupByMediaNameOrderByPublishDate(searchSourceBuilder);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }



    @Override
    public int updateSensitiveInformation(String[] ids, String sensitive) {

        //修改ES中的数据
        for (String id : ids) {
            PoPublicOpinion poPublicOpinion = selectPoPublicOpinionById(id);
            if (sensitive.equals("正面")) {
                poPublicOpinion.setIspositive(1);
                poPublicOpinion.setIsneutral(0);
                poPublicOpinion.setIsnegative(0);
            } else if (sensitive.equals("中性")) {
                poPublicOpinion.setIspositive(0);
                poPublicOpinion.setIsneutral(1);
                poPublicOpinion.setIsnegative(0);
            } else if (sensitive.equals("负面")) {
                poPublicOpinion.setIspositive(0);
                poPublicOpinion.setIsneutral(0);
                poPublicOpinion.setIsnegative(1);
            }
            try {
                elasticsearchBasicService.updateOpinionIndex(poPublicOpinion);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return 1;
    }

    @Override
    public int joinTheForecast(String[] ids, String level, Long userId, Long deptId, String tenantCode) {
        int resRemove = removeTheForecast(ids, userId, deptId, tenantCode);
        int resJoin = poPublicOpinionMapper.joinTheForecast(ids, level, userId, deptId, tenantCode);
        new Thread(() -> warningTask.sendWarning(ids, tenantCode, level)).start();
        return resJoin;
    }

    public int removeTheForecast(String[] ids, Long userId, Long deptId, String tenantCode) {
        return poPublicOpinionMapper.removeTheForecast(ids, userId, deptId, tenantCode);
    }

    @Override
    public List<PoPublicOpinion> selectPoPublicOpinionListByIds(String[] ids) {
        return esUtil.getMatchOpinionByIds(Arrays.asList(ids.clone()));
    }


    @Override
    public PageInfo<PoPublicOpinion> queryWarningList(OpinionParameterVo parameter, Integer pageNum, Integer pageSize) {
        //构建查询语句
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //时间段过滤
        if (StringUtils.isNotEmpty(parameter.getTimeType())) {
            if (!parameter.getTimeType().equals("all")) {
                HashMap hashMap = DateUtils.getStartEndTime(parameter.getTimeType(), parameter.getStartDateTime(), parameter.getEndDateTime());
                Date beginPublishDay = (Date) hashMap.get("beginPublishDay");
                Date endPublishDay = (Date) hashMap.get("endPublishDay");
                boolQueryBuilder=elasticsearchQueryBuilderService.boolQueryBuilder(boolQueryBuilder,beginPublishDay,endPublishDay);
            }
        } else if (StringUtils.isEmpty(parameter.getTimeType()) && parameter.getStartDateTime() != null) {
            boolQueryBuilder=elasticsearchQueryBuilderService.boolQueryBuilderStartTime(boolQueryBuilder,parameter.getStartDateTime());
        } else if (StringUtils.isEmpty(parameter.getTimeType()) && parameter.getEndDateTime() != null) {
            boolQueryBuilder=elasticsearchQueryBuilderService.boolQueryBuilderEndTime(boolQueryBuilder,parameter.getEndDateTime());
        }
        //媒体类型过滤
        if (parameter.getMediaType() != null && parameter.getMediaType().size() > 0) {
            List<Integer> carries = new ArrayList<>();
            for (int i = 0; i < parameter.getMediaType().size(); i++) {
                carries.add(ChinaMediaTypeEnum.getCarrieByName(parameter.getMediaType().get(i)));
            }
            boolQueryBuilder.must(QueryBuilders.termsQuery("carrie", carries));
        }
        //关键词
        if (StringUtils.isNotEmpty(parameter.getKeywords())) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("title", parameter.getKeywords()));
        }

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        List<String> ids = poPublicOpinionMapper.queryWarningIds(parameter.getLevel(), parameter.getTenantCode());
        searchSourceBuilder.postFilter(QueryBuilders.termsQuery("id", ids));
        searchSourceBuilder.query(boolQueryBuilder);

        //排序
        if (parameter.getSort() != null && parameter.getSort().equals("desc")) {
            List<SortBuilder<?>> sorts = new ArrayList<>();
            SortBuilder sortBuilder = SortBuilders.fieldSort("publishTime").order(SortOrder.DESC);
            sorts.add(sortBuilder);
            searchSourceBuilder.sort(sorts);
        } else if (parameter.getSort() != null && parameter.getSort().equals("asc")) {
            List<SortBuilder<?>> sorts = new ArrayList<>();
            SortBuilder sortBuilder = SortBuilders.fieldSort("publishTime").order(SortOrder.ASC);
            sorts.add(sortBuilder);
            searchSourceBuilder.sort(sorts);
        }

        try {
            return esUtil.search(searchSourceBuilder, pageNum, pageSize, PoPublicOpinion.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<NameValue> getForecastMediaType(OpinionParameterVo parameter) {
        List<String> ids = poPublicOpinionMapper.queryWarningIds(parameter.getLevel(), parameter.getTenantCode());
        //构建查询语句
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termsQuery("id", ids));
        //时间段过滤
        if (StringUtils.isNotEmpty(parameter.getTimeType())) {
            if (!parameter.getTimeType().equals("all")) {
                HashMap hashMap = DateUtils.getStartEndTime(parameter.getTimeType(), parameter.getStartDateTime(), parameter.getEndDateTime());
                Date beginPublishDay = (Date) hashMap.get("beginPublishDay");
                Date endPublishDay = (Date) hashMap.get("endPublishDay");
                boolQueryBuilder=elasticsearchQueryBuilderService.boolQueryBuilder(boolQueryBuilder,beginPublishDay,endPublishDay);
            }
        } else if (StringUtils.isEmpty(parameter.getTimeType()) && parameter.getStartDateTime() != null) {
            boolQueryBuilder=elasticsearchQueryBuilderService.boolQueryBuilderStartTime(boolQueryBuilder,parameter.getStartDateTime());
        } else if (StringUtils.isEmpty(parameter.getTimeType()) && parameter.getEndDateTime() != null) {
            boolQueryBuilder=elasticsearchQueryBuilderService.boolQueryBuilderEndTime(boolQueryBuilder,parameter.getEndDateTime());
        }
        //媒体类型过滤
        if (parameter.getMediaType() != null && parameter.getMediaType().size() > 0) {
            boolQueryBuilder.must(QueryBuilders.termsQuery("mediaType", parameter.getMediaType()));
        }

        //关键词
        if (StringUtils.isNotEmpty(parameter.getKeywords())) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("title", parameter.getKeywords()));
        }

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(boolQueryBuilder);
        try {
            return esUtil.getCountGroupByMediaType(searchSourceBuilder);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }



    //生成token
    //key是我们约定好的一个key值
    public String generate_token(String key, long time) {
        return md5(key + time + key);
    }


    public Map sendJSon(String actionUrl, ObjectNode jsonObject) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> request = new HttpEntity<>(jsonObject.toString(), headers);
        RestTemplate restTemplate = new RestTemplate();
        Map result = restTemplate.postForObject(actionUrl, request, Map.class);
        return result;
    }


    @Override
    public AjaxResult queryOpinionByDataServer(SearchParameterVo parameter, Integer pageNum, Integer pageSize) {

        //检索条件控制参数
        String paramsJson;

        String startTime = null;
        String endTime = null;
        if (StringUtils.isNotEmpty(parameter.getTimeType())) {
            HashMap hashMap = DateUtils.getStartEndTime(parameter.getTimeType(), parameter.getStartDateTime(), parameter.getEndDateTime());
            Date beginPublishDay = (Date) hashMap.get("beginPublishDay");
            startTime = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", beginPublishDay);
            Date endPublishDay = (Date) hashMap.get("endPublishDay");
            endTime = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", endPublishDay);
        }
        String actionUrl = baseUrl + apiUrl;

        ParamsJson params = new ParamsJson();
        params.setPublishedStartTime(startTime);
        params.setPublishedEndTime(endTime);
        if(StringUtils.isNotEmpty(parameter.getSearchArea())&&parameter.getSearchArea().equals("all")){
            params.setMatchType(1);
        }else if(StringUtils.isNotEmpty(parameter.getSearchArea())&&parameter.getSearchArea().equals("title")){
            params.setMatchType(2);
        }else if(StringUtils.isNotEmpty(parameter.getSearchArea())&&parameter.getSearchArea().equals("content")){
            params.setMatchType(3);
        }
        params.setSearchKeyword(parameter.getKeyWords());
        params.setSensitivityType(1);
        //排序类型(1:升序 2:降序)
        params.setSort(1);
        //页数设置
        params.setPage(pageNum);
        //每页大小设置
        params.setPageSize(pageSize);
        paramsJson = JSONObject.toJSONString(params);

        //授权校验参数
        String accessToken= getAccessToken();

        //3、请求Api接口
        Map<String, String> paramsMap = new HashMap<>();
        paramsMap.put("accessToken", accessToken);
        paramsMap.put("paramsJson", paramsJson);

        String s = sendPost(actionUrl, paramsMap);

        System.out.println("*****************************************************************");
        System.out.println("actionUrl：" + actionUrl);
        System.out.println("jsonObject：" + s);
        System.out.println("*****************************************************************");
        JSONObject jsonObject = JSONObject.parseObject(s);
        return AjaxResult.success(jsonObject);
    }







    /**
     * 获取舆情数据并生成excel
     *
     * @param parameter
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public AjaxResult downloadCsvDataFromServeCenter(SearchParameterVo parameter, Integer pageNum, Integer pageSize) {
        List<PoPublicOpinion> opinions = new ArrayList<>();
        AjaxResult ajaxResult = queryOpinionByDataServer(parameter, pageNum, pageSize);
        if (ajaxResult.containsKey("data")) {
            LinkedHashMap res = (LinkedHashMap) ajaxResult.get("data");
            ArrayList results = (ArrayList) res.get("result");
            results.forEach(item -> {
                JSONObject opinionObject = JSONObject.parseObject(JSONObject.toJSONString(item));
                PoPublicOpinion opinion = opinionObject.toJavaObject(PoPublicOpinion.class);
                opinions.add(opinion);
            });

            try {
                esUtil.insertOpinionIsNotExists(opinions);
            } catch (IOException e) {
                e.printStackTrace();
            }
            ExcelUtil<PoPublicOpinion> util = new ExcelUtil<>(PoPublicOpinion.class);
            return util.exportExcel(opinions, "社民情数据");
        } else {
            return AjaxResult.error("数据本地化失败");
        }
    }


    @Override
    public List<PoPublicOpinion> getNegativePublicOpinion(String beginPublishDay, String endPublishDay, int count) {

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 设置查询条件
        searchSourceBuilder.query(QueryBuilders.boolQuery()
                .must(QueryBuilders.matchAllQuery())
                .filter(QueryBuilders.termQuery("isnegative", 1)));
        //排序
        List<SortBuilder<?>> sorts = new ArrayList<>();
        SortBuilder sortBuilder = SortBuilders.fieldSort("publishTime").order(SortOrder.DESC);
        sorts.add(sortBuilder);
        searchSourceBuilder.sort(sorts);
        // 构建去重聚合操作
        TermsAggregationBuilder dedupFieldAggregation = AggregationBuilders.terms("dedup_field")
                .field("title.keyword")
                .size(10)
                .subAggregation(
                        new TopHitsAggregationBuilder("dedup_docs")
                                .sort("publishTime", SortOrder.DESC)
                                .size(1)
                );

        // 将聚合操作添加到查询请求中
        searchSourceBuilder.aggregation(dedupFieldAggregation);

        try {
            return esUtil.searchRemoveDuplicates(searchSourceBuilder, PoPublicOpinion.class, count);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }


    @Override
    public List<NameListValue> getSentimentByPublishTime(String beginPublishDay, String endPublishDay) {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //构造QueryBuilder
        BoolQueryBuilder matchQueryBuilder = QueryBuilders.boolQuery();
        if (StringUtils.isEmpty(beginPublishDay) && beginPublishDay != null) {
            matchQueryBuilder=elasticsearchQueryBuilderService.boolQueryBuilderStartTime(matchQueryBuilder,DateUtils.parseDate("beginPublishDay"));
        } else if (StringUtils.isEmpty(endPublishDay) && endPublishDay != null) {
            matchQueryBuilder=elasticsearchQueryBuilderService.boolQueryBuilderEndTime(matchQueryBuilder,DateUtils.parseDate("endPublishDay"));
        }
        searchSourceBuilder.query(matchQueryBuilder);
        return esUtil.getCountGroupByPublishDateSentiment(searchSourceBuilder);
    }


    @Override
    public List<EventAndTopic> queryEventAndTopic(String tenantCode) {
        return poPublicOpinionMapper.queryEventAndTopic(tenantCode);
    }


    @Override
    public AjaxResult downloadDataFromServeCenter(SearchParameterVo parameter, Integer pageNum, Integer pageSize) {
        AtomicInteger count = new AtomicInteger();
        AjaxResult ajaxResult = queryOpinionByDataServer(parameter, pageNum, pageSize);
        if (ajaxResult.containsKey("data")) {
            LinkedHashMap res = (LinkedHashMap) ajaxResult.get("data");
            ArrayList results = (ArrayList) res.get("result");
            results.forEach(item -> {
                JSONObject opinionObject = JSONObject.parseObject(JSONObject.toJSONString(item));
                String id = opinionObject.getString("id");
                String jSONString = opinionObject.toJSONString();
                int success = esUtil.indexOpinion(jSONString, id);
                count.addAndGet(success);
            });
            if (count.get() > 0) {
                return AjaxResult.success("数据本地化成功");
            } else {
                return AjaxResult.error("数据本地化失败");
            }
        } else {
            return AjaxResult.error("数据本地化失败");
        }
    }


}
